using System.ComponentModel;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using Daemon.Model;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.ResponseCompression;
using Autofac;
using DaemonAPI.Middleware;
using Daemon.Middleware;
using Daemon.Common.Elasticsearch;
using Microsoft.AspNetCore.Authorization;
using Daemon.Common.Auth;
using DaemonAPI.SchdulerJob;
using DaemonAPI.Hubs;
using Daemon.Common.Handlers;

namespace DaemonAPI
{
    public class Startup
    {
        private string connection = string.Empty;
        public Startup(IConfiguration configuration, IWebHostEnvironment env)
        {
            var builder = new ConfigurationBuilder().SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json")
                .AddJsonFile("autofac.json");
            connection = configuration.GetSection("AppSettings:DefaultConnection").Value;
            Configuration = builder.Build();
        }

        public IConfiguration Configuration { get; }
        public Autofac.IContainer Container { get; set; }


        // This method gets called by the runtime. Use this method to add services to the container.
        public IServiceProvider ConfigureServices(IServiceCollection services)
        {
            services.AddHttpClient();
            services.AddDbContext<ApiDBContent>(option =>
            {
                //option.UseSqlite("Filename=./learn01.db");
                option.UseMySql(connection, Microsoft.EntityFrameworkCore.ServerVersion.Parse("5.7.27-log"));
            });

            services.AddSingleton<DbContext>(provider => provider.GetService<ApiDBContent>());
            services.AddSingleton<IElasticsearchConfigProvider>(provider => new ElasticsearchConfigProvider(new ElasticsearchConfig() { Nodes = new List<ElasticsearchNode> { new ElasticsearchNode() { Host = "127.0.0.1", Port = 9200 } } }));
            services.AddSingleton<IElasticsearchClient, ElasticsearchClient>();
            services.AddDaemonProvider(Configuration, 2, true, true, false, false);
            services.AddControllers();
            services.AddJwtBearExt(Configuration);
            services.AddConfigCors(Configuration);
            services.AddResponseCompression(options =>
            {
                options.Providers.Add<GzipCompressionProvider>();
            });
            services.Register();
            services.AddSignalR();
            return RegisterExtensions.RegisterAutofac(services, Configuration, this.Container);
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {

            app.UseResponseCompression();
            //Enable Authentication
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseStaticHttpContext().UseServiceProvider();
            app.UseCors("qwer");
            app.UseHttpsRedirection();
            app.UseRouting();

            app.UseAuthentication();
            app.UseAuthorization();
            app.UseSwaggerUI();

            app.SetFileExtensionContentType();
            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
                endpoints.MapHub<UserOrderHub>("/api/userOrderHub");
            });

            HandleStart();
        }

        static void HandleStart()
        {
            try
            {
                new Scheduler().Start().GetAwaiter().GetResult();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
        }
    }
}
